package br.com.rapidrest.ioc;

import java.lang.reflect.Field;

import javax.servlet.http.HttpSession;

import br.com.rapidrest.annotation.SessionStored;
import br.com.rapidrest.chain.BasicChainContext;
import br.com.rapidrest.exception.InjectionException;

public class SessionStoredFieldHandler implements FieldHandler {

	private static final String SESSION_STORED_FIELD_PREFIX = "rapidrest.session.stored.field";

	@Override
	public void handle(Field field, Object target, BasicChainContext context)
			throws InjectionException {
		if (isSessionStored(field)) {
			try {
				HttpSession session = context.getRequest().getSession();
				Object fieldValue = retrieveFromSession(field, target, session);
				field.setAccessible(true);
				field.set(target, fieldValue);
			} catch (IllegalArgumentException e) {
				throw new InjectionException(e);
			} catch (IllegalAccessException e) {
				throw new InjectionException(e);
			}
		}
	}

	protected boolean isSessionStored(Field field) {
		return field.isAnnotationPresent(SessionStored.class);
	}

	protected Object retrieveFromSession(Field field, Object target,
			HttpSession session) {
		String sessionKey = SESSION_STORED_FIELD_PREFIX + "."
				+ target.getClass().getName() + "." + field.getName();
		return session.getAttribute(sessionKey);
	}

	@Override
	public void end(Field field, Object target, BasicChainContext context)
			throws InjectionException {
		if (isSessionStored(field)) {
			try {
				HttpSession session = context.getRequest().getSession();
				field.setAccessible(true);
				Object fieldValue = field.get(target);
				
				String sessionKey = SESSION_STORED_FIELD_PREFIX + "."
						+ target.getClass().getName() + "." + field.getName();
				
				session.setAttribute(sessionKey, fieldValue);
			} catch (IllegalArgumentException e) {
				throw new InjectionException(e);
			} catch (IllegalAccessException e) {
				throw new InjectionException(e);
			}
		}
	}

}
